package com.motong.gongdan.controller.system;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.motong.gongdan.config.ResponseData;
import com.motong.gongdan.config.auth.UserLoginToken;
import com.motong.gongdan.constant.CommonConstant;
import com.motong.gongdan.entity.Broadcast;
import com.motong.gongdan.entity.WorkReport;
import com.motong.gongdan.service.*;
import com.motong.gongdan.util.LoginUtil;
import com.motong.gongdan.util.RedisUtil;
import com.motong.gongdan.util.TimeUtil;
import com.motong.gongdan.vo.H5Vo.Dashboard.query.GetAllQuery;
import com.motong.gongdan.vo.H5Vo.Dashboard.vo.WorkOrderStatisticsVo;
import com.motong.gongdan.vo.resp.*;
import com.motong.gongdan.vo.system.Broadcast.query.BroadcastGetListQuery;
import com.motong.gongdan.vo.system.DataBoard.query.WorkReportGroupByProcessQuery;
import com.motong.gongdan.vo.system.DataBoard.vo.ReportGroupProcessInfo;
import com.motong.gongdan.vo.system.DataBoard.vo.WorkReportDetailVo;
import com.motong.gongdan.vo.system.DataBoard.vo.WorkReportGroupByProcessVo;
import com.motong.gongdan.vo.system.common.query.GetSearchCacheQuery;
import com.motong.gongdan.vo.system.common.vo.VoiceCallsInfo;
import com.motong.gongdan.vo.system.dataController.query.WorkOrderOverviewQuery;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.TimeUnit;

import static com.motong.gongdan.constant.CommonConstant.WORK_REPORT_DASHBOARD_SEARCHED_ID_CACHE;

/**
 * @author:fff
 * @time:2022/3/24
 */
@Api(value = "车间看板", tags = {"车间看板"})
@RestController
@RequestMapping(value = "/sys/data/")
public class DataController {
    @Resource
    WorkOrderService workOrderService;
    @Resource
    WorkReportService workReportService;
    @Resource
    ProcessesService processesService;
    @Resource
    private DashboardService dashboardService;
    @Resource
    private BaseController baseController;
    @Resource
    private BroadcastService broadcastService;
    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @UserLoginToken
    @ApiOperation(value = "车间看板中间数据&&工单产出分析&&员工绩效top5")
    @RequestMapping(value = "data_first", method = RequestMethod.POST)
    public ResponseData dataFirst() {
        DataFirstResp dfr = new DataFirstResp();
        List<YieldTimeResp> list = workOrderService.getBaseMapper()
                .getDataByTime(TimeUtil.getTimeByDayTwo(-10),
                        TimeUtil.getDateDefaultStringTwo(new Date()));
        dfr.setProduce(list);
        List<PerformanceResp> pList = workReportService.getBaseMapper().getPerformanceTop5();
        dfr.setPerformance(pList);
        Map<String, Object> map = ((JSONObject) RedisUtil.get("data:home:num:" + LoginUtil.getLoginUserFactory()));

        if (Objects.nonNull(map)) {
            // 今日产量总数(今日,最后一道工序报工数)
            GetAllQuery getAllQuery = new GetAllQuery().setStartTime(DateUtil.beginOfDay(new Date()).toString()).setEndTime(DateUtil.endOfDay(new Date()).toString());
            WorkOrderStatisticsVo workOrderStatisticsVo = dashboardService.workOrderStatistics(getAllQuery);
            map.put("dayProduceTotalNumber", workOrderStatisticsVo.getFinishNum());
            // 今日报工总数
            QueryWrapper<WorkReport> countQw = new QueryWrapper<WorkReport>().between("create_time", getAllQuery.getStartTime(), getAllQuery.getEndTime()).select("SUM(IFNULL(good_product_number,0)) total");
            Map<String, Object> numberData = Optional.ofNullable(workReportService.getMap(countQw)).orElse(Collections.emptyMap());
            map.put("dayReportTotalNumber", numberData.getOrDefault("total", 0));
        }
        dfr.setDataNum(map);
        return ResponseData.success(dfr);
    }


    @UserLoginToken
    @ApiOperation(value = "不良品分析&&分布&&任务执行进度")
    @RequestMapping(value = "data_second", method = RequestMethod.POST)
    public ResponseData dataSecond() {

        DataSecondResp dsr = new DataSecondResp();
        List<BadProductDataResp> badProduct = workReportService.getBaseMapper().getBadProductForData(TimeUtil.getTimeByDayTwo(-10),
                TimeUtil.getDateDefaultStringTwo(new Date()));
        dsr.setBadProductData(badProduct);
        List<PerformanceResp> pList = workReportService.getBaseMapper().getBadProductForDataA();
        dsr.setBadProduct(pList);
        List<DataThirdResp> list = processesService.getBaseMapper().getDataThird();
        dsr.setMission(list);
        return ResponseData.success(dsr);

    }

    @UserLoginToken
    @ApiOperation("工单概览")
    @PostMapping("workOrderOverview")
    public ResponseData<List<WorkOrderResp>> workOrderOverview(@RequestBody(required = false) WorkOrderOverviewQuery workOrderOverviewQuery) {
        Object cacheOrderCondition = baseController.getSearchCache(new GetSearchCacheQuery().setCacheName(CommonConstant.H5_DASHBOARD_H5ORDER_SORT_CONDITION_NAME).setType(1)).getData();
        workOrderOverviewQuery = Optional.ofNullable(workOrderOverviewQuery).orElse(new WorkOrderOverviewQuery());
        if (Objects.nonNull(cacheOrderCondition)) {
            String[] sortCondition = cacheOrderCondition.toString().split(",");
            if (sortCondition.length == 2) {
                workOrderOverviewQuery.setOrderBy(sortCondition[0]);
                workOrderOverviewQuery.setSort(sortCondition[1]);
            }

        }
        Page<WorkOrderResp> data = workOrderService.getWorkOrderOverview(workOrderOverviewQuery);
        return ResponseData.success(data.getRecords(), data.getTotal());
    }


    @UserLoginToken
    @ApiOperation("报工看板——报工列表")
    @PostMapping("workReportGroupByProcess")
    public ResponseData<WorkReportGroupByProcessVo> WorkReportGroupByProduct(@RequestBody(required = false) WorkReportGroupByProcessQuery query) {
        Integer userId = LoginUtil.getLoginUserId();
        Date currentDate = new Date();
        query = Optional.ofNullable(query).orElse(new WorkReportGroupByProcessQuery());
        query.setReportStartTime(Optional.ofNullable(query.getReportStartTime()).orElse(DateUtil.beginOfDay(currentDate)));
        query.setReportEndTime(Optional.ofNullable(query.getReportEndTime()).orElse(DateUtil.endOfDay(currentDate)));
        Page<ReportGroupProcessInfo> data = workReportService.workReportGroupByProcessList(new Page<>(query.getPage(), query.getLimit()), query);
        WorkReportGroupByProcessVo finalData = new WorkReportGroupByProcessVo();
        finalData.setDataList(data.getRecords()).setVoiceCallsInfos(Collections.emptyList());
        // 获取语音播报信息
        String dateStr = new DateTime(currentDate).toDateStr();
        Object cachedReportIdsO = redisTemplate.opsForHash().get(WORK_REPORT_DASHBOARD_SEARCHED_ID_CACHE.concat(dateStr), userId.toString());
        // 轮次
        Integer roundNum = query.getRoundNum();
        // 间隔时间
        int intervalTime = query.getIntervalTime().multiply(BigDecimal.valueOf(60)).intValue();
        // 后续语音播报
        List<Broadcast> broadcasts = new ArrayList<>();
        List<VoiceCallsInfo> voiceCallsInfos = new ArrayList<>();
        //获取后续播报
//        LambdaQueryWrapper<Broadcast> secondOrMoreBroadcastQW = new LambdaQueryWrapper<Broadcast>().eq(Broadcast::getBelongModule, 0).eq(Broadcast::getState, 0)
//                .le(Broadcast::getNoticeTime, currentDate).ge(Broadcast::getNoticeTime, query.getReportStartTime()).eq(Broadcast::getInfoUser, userId);
//        List<Broadcast> secondOrMoreBroadcasts = broadcastService.list(secondOrMoreBroadcastQW);
        BroadcastGetListQuery broadcastGetListQuery = new BroadcastGetListQuery().setNoticeTimeStart(query.getReportStartTime()).setNoticeTimeEnd(currentDate)
                .setInfoUser(LoginUtil.getLoginUserId());
        List<Broadcast> secondOrMoreBroadcasts = broadcastService.getList(broadcastGetListQuery).getRecords();
        secondOrMoreBroadcasts.forEach(i -> {
            voiceCallsInfos.add(new VoiceCallsInfo().setText(i.getText()));
            i.setRoundNum(i.getRoundNum() - 1).setState(i.getRoundNum() == 0 ? 1 : 0).setNoticeTime(i.getRoundNum() == 0 ? i.getNoticeTime() : DateUtil.offsetMinute(currentDate, intervalTime)).setIntervalTime(intervalTime);
            broadcasts.add(i);
        });
        //首次语音播报
        WorkReportGroupByProcessQuery broadcastSearchCondition = new WorkReportGroupByProcessQuery().setVerifyState("0").setProcessIds(query.getProcessIds())
                .setReportStartTime(DateUtil.beginOfDay(currentDate)).setReportEndTime(DateUtil.endOfDay(currentDate));
        List<String> cachedReportIds = Objects.nonNull(cachedReportIdsO) ? JSONUtil.toList(cachedReportIdsO.toString(), String.class) : new ArrayList<>();
        broadcastSearchCondition.setExcludedWorkReportIds(cachedReportIds);
        List<WorkReportDetailVo> broadcastOriData = workReportService.getBaseMapper().workReportListByProcessCodes(broadcastSearchCondition);
        if (!CollectionUtils.isEmpty(broadcastOriData)) {
            broadcastOriData.forEach(i -> {
                cachedReportIds.add(i.getWorkReportId().toString());
                //处理小数点问题
                String workReportNumString = i.getWorkReportNum().setScale(2, RoundingMode.HALF_UP).toString();
                if (StringUtils.hasLength(workReportNumString) && workReportNumString.contains(".")) {
                    String[] split = workReportNumString.split("\\.");
                    if (split[1].contains("00")) {
                        workReportNumString = split[0];
                    } else if (split[1].endsWith("0")) {
                        workReportNumString = split[0].concat(".").concat(split[1].substring(0, 1));
                    }
                }
                String text = String.format("%s报工%s%s工序%s%s", i.getWorkReportUserName(), i.getProductName(), i.getProcessName(), workReportNumString, i.getUnitName());
                // 多次播报存储表格
                if (roundNum > 1) {
                    Broadcast secondBroadcast = new Broadcast().setBelongModule(0).setNoticeTime(DateUtil.offsetMinute(currentDate, intervalTime)).setState(0)
                            .setText(text).setCreateTime(currentDate).setRoundNum(roundNum - 1).setIntervalTime(intervalTime).setInfoUser(userId).setRelationId(i.getWorkReportId());
                    broadcasts.add(secondBroadcast);
                }
                voiceCallsInfos.add(new VoiceCallsInfo().setText(text));
            });
            redisTemplate.opsForHash().put(WORK_REPORT_DASHBOARD_SEARCHED_ID_CACHE.concat(dateStr), userId.toString(), JSONUtil.toJsonStr(cachedReportIds));
        }
        finalData.setVoiceCallsInfos(voiceCallsInfos);
        redisTemplate.opsForHash().getOperations().expire(WORK_REPORT_DASHBOARD_SEARCHED_ID_CACHE.concat(dateStr), 1, TimeUnit.DAYS);
        if (!CollectionUtils.isEmpty(broadcasts)) {
            broadcastService.saveOrUpdateBatch(broadcasts);
        }
        return ResponseData.success(finalData, data.getTotal());
    }

}

